/*
 * connection.hpp
 *
 *  Created on: Dec 5, 2010
 *      Author: daniel
 */

#ifndef WA_CONNECTION_HPP_
#define WA_CONNECTION_HPP_

#include <boost/shared_ptr.hpp>
#include <list>

#define MAX_BUFFER_SIZE 1024*16

namespace doeplus{ namespace webapp{ namespace helpers {


class buffer {

public:
	typedef boost::shared_ptr<buffer> ptr;

private:
	char _buffer[MAX_BUFFER_SIZE+1];
//	boost::array<char, MAX_BUFFER_SIZE+1> _buffer;
	std::size_t size;

public:

	buffer(): size(0)
	{

	}

	void reset(){
		this->size	= 0;
	}

	int max_size(){
		return MAX_BUFFER_SIZE;
	}

	char* get_next(){
		return &this->_buffer[this->size];
	}

	void add_size(std::size_t add_size){
		this->size += add_size;
	}

	int remaining_size(){
		return MAX_BUFFER_SIZE-this->size;
	}
	bool is_full(){
		return this->size==MAX_BUFFER_SIZE;
	}

	boost::asio::mutable_buffers_1 mutable_buffer(){
		return boost::asio::buffer(this->get_next(),this->remaining_size());
	}


};

class buffer_factory
{
private:
	typedef std::list<buffer::ptr> buffer_queue;
	static buffer_queue& get_queue(){
		static buffer_queue queue;
		return queue;
	}
public:
	static buffer::ptr get(){
		buffer_queue &queue	= buffer_factory::get_queue();
		if(queue.empty()){
			return buffer::ptr(new buffer());
		}
		buffer::ptr return_buffer	= queue.back();
		queue.pop_back();
		return return_buffer;
	}

	static void put(buffer::ptr buffer){
		buffer_queue &queue	= buffer_factory::get_queue();
		queue.push_back(buffer);
	}

};


} } } // doeplus::webapp::helpers

#endif

